package com.zbangmall.util.algorithm;

import com.zbangmall.util.common.CheckUtil;
import com.zbangmall.util.common.FileUtil;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;

/**
 * 文件编码相关的一些工具函数
 */
public class FileEncodingUtil {
	/**
	 * 把指定文件或目录转换成指定的编码
	 *
	 * @param fileName        要转换的文件
	 * @param fromCharsetName 源文件的编码
	 * @param toCharsetName   要转换的编码
	 */
	public static void convert(String fileName, String fromCharsetName, String toCharsetName) {
		convert(new File(fileName), fromCharsetName, toCharsetName, null);
	}

	/**
	 * 把指定文件或目录转换成指定的编码
	 *
	 * @param file            要转换的文件或目录
	 * @param fromCharsetName 源文件的编码
	 * @param toCharsetName   要转换的编码
	 */
	public static void convert(File file, String fromCharsetName, String toCharsetName) {
		convert(file, fromCharsetName, toCharsetName, null);
	}

	/**
	 * 把指定文件或目录转换成指定的编码
	 *
	 * @param fileName        要转换的文件或目录
	 * @param fromCharsetName 源文件的编码
	 * @param toCharsetName   要转换的编码
	 * @param filter          文件名过滤器
	 */
	public static void convert(String fileName, String fromCharsetName, String toCharsetName, FilenameFilter filter) {
		convert(new File(fileName), fromCharsetName, toCharsetName, filter);
	}

	/**
	 * 把指定文件或目录转换成指定的编码
	 *
	 * @param file            要转换的文件或目录
	 * @param fromCharsetName 源文件的编码
	 * @param toCharsetName   要转换的编码
	 * @param filter          文件名过滤器
	 */
	public static void convert(File file, String fromCharsetName, String toCharsetName, FilenameFilter filter) {
		if (file.isDirectory()) {
			List<File> list = CheckUtil.valid(filter) ? FileUtil.listFileFilter(file, filter) :
					FileUtil.listFile(file);
			if (CheckUtil.valid(list)) {
				for (File f : list) {
					convert(f, fromCharsetName, toCharsetName, filter);
				}
			}
		} else {
			if (filter == null || filter.accept(file.getParentFile(), file.getName())) {
				String fileContent = getFileContentFromCharset(file, fromCharsetName);
				saveFile2Charset(file, toCharsetName, fileContent);
			}
		}
	}

	/**
	 * 以指定编码方式读取文件，返回文件内容
	 *
	 * @param file            要转换的文件
	 * @param fromCharsetName 源文件的编码
	 */
	public static String getFileContentFromCharset(File file, String fromCharsetName) {
		String str = "";
		if (!Charset.isSupported(fromCharsetName)) {
			throw new UnsupportedCharsetException(fromCharsetName);
		}
		try (InputStream inputStream = new FileInputStream(file);
			 InputStreamReader reader = new InputStreamReader(inputStream, fromCharsetName)
		) {
			char[] chs = new char[(int) file.length()];
			reader.read(chs);
			str = new String(chs).trim();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 以指定编码方式写文本文件，存在会覆盖
	 *
	 * @param file          要写入的文件
	 * @param toCharsetName 要转换的编码
	 * @param content       文件内容
	 */
	public static void saveFile2Charset(File file, String toCharsetName, String content) {
		if (!Charset.isSupported(toCharsetName)) {
			throw new UnsupportedCharsetException(toCharsetName);
		}
		try (
				OutputStream outputStream = new FileOutputStream(file);
				OutputStreamWriter outWrite = new OutputStreamWriter(outputStream, toCharsetName)
		) {
			outWrite.write(content);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
